<?php

declare(strict_types=1);
/**
 * This file is part of MoChat.
 * @link     https://mo.chat
 * @document https://mochat.wiki
 * @contact  group@mo.chat
 * @license  https://github.com/mochat-cloud/mochat/blob/master/LICENSE
 */
namespace MoChat\Plugin\Radar\Action\Sidebar;

use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\Middlewares;
use Hyperf\HttpServer\Annotation\RequestMapping;
use MoChat\App\Common\Middleware\SidebarAuthMiddleware;
use MoChat\App\Utils\File;
use MoChat\Framework\Action\AbstractAction;
use MoChat\Framework\Constants\ErrorCode;
use MoChat\Framework\Exception\CommonException;
use MoChat\Framework\Request\ValidateSceneTrait;
use MoChat\Plugin\Radar\Logic\StoreLogic;

/**
 * 互动雷达 - 增加.
 *
 * Class RadarArticle.
 * @Controller
 */
class RadarArticle extends AbstractAction
{
    use ValidateSceneTrait;

    /**
     * @Inject
     * @var StoreLogic
     */
    protected $storeLogic;

    /**
     * @Middlewares({
     *     @Middleware(SidebarAuthMiddleware::class)
     * })
     * @RequestMapping(path="/sidebar/radar/radarArticle", methods="get")
     * @return array 返回数组
     * @throws \League\Flysystem\FilesystemException
     */
    public function handle(): array
    {
        $user = user();
        // 判断用户绑定企业信息
        if (! isset($user['corpId'])) {
            throw new CommonException(ErrorCode::INVALID_PARAMS, '未选择登录企业，不可操作');
        }

        // 参数验证
        $url = $this->request->input('url');
        if (str_contains($url, 'https')) {
            $ch = curl_init();
            $user_agent = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36';
            curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            $html = curl_exec($ch);
            curl_close($ch);
        } else {
            $html = file_get_contents($url);
        }
        // 去除微信中的抓取干扰代码
        $html = str_replace('<!--headTrap<body></body><head></head><html></html>-->', '', $html);

        // 文章标题、描述
        [$title, $description, $content, $author, $cover] = $this->regexHtml($html, $url);
        /* 图片处理 */
        $imgArr = [];
        // 匹配img标签
        preg_match_all("/<img([^>]*)\\s*src=('|\")([^'\"]+)('|\")/", $content, $imgArr);
        $imgArr[3] = array_unique($imgArr[3]); // 去除重复
        $imgArr2 = $imgArr[3];

        // 下载，替换图片链接
        foreach ($imgArr2 as $k => $v) {
            $pathFileName = File::generateFullFilename('png');
            $url = File::uploadUrlImage($v, $pathFileName);
            $content = str_replace($v, $url['path'], $content);
        }

        return [
            'title' => $title,
            'cover_url' => $cover['path'] ?? '',
            'coverFullUrl' => $cover['fullPath'] ?? '',
            'coverName' => ! empty($cover['path']) ? $this->getPathName($cover['path']) : '',
            'desc' => $description,
            'author' => $author,
            'content' => $content,
        ];
    }

    /**
     * 验证规则.
     *
     * @return array 响应数据
     */
    protected function rules(): array
    {
        return [
        ];
    }

    /**
     * 验证错误提示.
     * @return array 响应数据
     */
    protected function messages(): array
    {
        return [
        ];
    }

    private function regexHtml(string $html, string $url): array
    {
        // Description
        $description = $this->getDescription($html, $url);

        // Title
        $title = $this->getTitle($html);

        // Content
        $content = $this->getContent($html, $url);

        // Author
        $author = $this->getAuthor($html, $url);

        // Cover
        $cover = $this->getCover($html);

        return [$title, $description, $content, $author, $cover];
    }

    private function getDescription(string $html, string $url): string
    {
        $description = '';
        preg_match('/<META\s+name=["\']description["\']\s+content=["\']([\w\W]*?)["\']/si', $html, $matches);
        if (empty($matches[1])) {
            preg_match('/<META\s+content=["\']([\w\W]*?)["\']\s+name=["\']description["\']/si', $html, $matches);
        }
        if (empty($matches[1])) {
            preg_match('/<META\s+http-equiv=["\']description["\']\s+content=["\']([\w\W]*?)["\']/si', $html, $matches);
        }
        if (empty($matches[1])) {
            preg_match('/<META\s+content=["\']description["\']\s+http-equiv=["\']([\w\W]*?)["\']/si', $html, $matches);
        }
        if (! empty($matches[1])) {
            $description = $matches[1];
        }
        if (empty($description) && ! str_contains($url, 'https')) {
            $matches = get_meta_tags($url);
            ! empty($matches['description']) && $description = $matches['description'];
        }
        return $description;
    }

    private function getTitle(string $html): string
    {
        $title = '';
        preg_match('/<TITLE>([\w\W]*?)<\/TITLE>/si', $html, $matches);
        if (! empty($matches[1])) {
            $title = $matches[1];
        }
        if (empty($matches[1])) {
            preg_match_all('/<title>(.*)<\/title>/', $html, $matches);
            if (! empty($matches)) {
                $title = $matches[1][0] ?? '';
            }
        }
        // 微信公众号-标题
        if (empty($title)) {
            $str_7 = substr($html, strripos($html, 'twitter:title') + 24);
            $str_8 = substr($str_7, 0, strrpos($str_7, 'twitter:creator') - 23);
            $title = mb_convert_encoding($str_8, 'UTF-8', 'UTF-8,GBK,GB2312,BIG5');
        }
        return $title;
    }

    private function getContent(string $html, string $url): string
    {
        $content = '';
        $type = (int) $this->request->input('type');
        if ($type === 3) {
            // 公众号文章内容
            if (str_contains($url, 'https://mp.weixin.qq.com')) {
                $str_16 = substr($html, strripos($html, "div class='rich_media_content'") + 76);
                $str_17 = substr($str_16, 0, strrpos($str_16, 'first_sceen__time') - 75); // 公众号文章正文
                $content = mb_convert_encoding($str_17, 'UTF-8', 'UTF-8,GBK,GB2312,BIG5');
                // 图片、视频不显示处理
                $content = str_replace(['data-src', 'preview.html'], ['src', 'player.html'], $content);
            } else {
                preg_match_all('/<div.*?>.*?<\\/div>/ism', $html, $matches);
                if (! empty($matches[0][0])) {
                    $content = $matches[0][0];
                }
            }
        }

        return $content;
    }

    private function getAuthor(string $html, string $url): string
    {
        $author = '';
        $matches = get_meta_tags($url);
        if (! empty($matches['author'])) {
            $author = $matches['author'];
        }
        if (empty($author)) {
            // 众号文章-作者
            $str_14 = substr($html, 0, strrpos($html, 'og:title') - 27);
            $str_15 = substr($str_14, strripos($str_14, 'author') + 17);
            $author = mb_convert_encoding($str_15, 'UTF-8', 'UTF-8,GBK,GB2312,BIG5');
        }
        return $author;
    }

    private function getCover(string $html): array
    {
        $cover = [];
        $pathFileName = File::generateFullFilename('png');
        preg_match_all("/<[img|IMG].*?src=[\\'|\"](.*?(?:[\\.gif|\\.jpg|\\.png]))[\\'|\"].*?[\\/]?>/", $html, $matches);
        if (! empty($matches[1])) {
            $image = $matches[1][0];
            str_contains($image, 'http') || $image = 'http:' . $image;
            $cover = File::uploadUrlImage($image, $pathFileName);
        }

        return $cover;
    }

    private function getPathName($coverPath): string
    {
        $path = explode('/', $coverPath);
        return array_pop($path);
    }
}
